﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using VIP.Extension;

namespace VIP {

    /// <summary>
    /// 导航任务类
    /// </summary>
    [Serializable]
    class NavigationTaskClass
    {
        public GameObject Player;
        public UnityAction<GameObject> EndMoveCallback;
        //剩余多少距离完成移动
        public float CompleteDistance;
        //是否立刻停止移动
        public bool IsStop;
    }

    public class VIPNavigation : VIPMonoSingleton<VIPNavigation>
    {

        /// <summary>
        /// 暂存的是正在移动的对象
        /// </summary>
        //[SerializeField]
        private List<NavigationTaskClass> ntcList = new List<NavigationTaskClass>();

        /// <summary>
        /// 设置目标点
        /// </summary>
        /// <param name="plyaer"></param>
        /// <param name="endPoint"></param>
        /// <returns></returns>
        public GameObject SetTargetPoint(GameObject plyaer, Vector3 endPoint)
        {
            return SetTargetPoint(plyaer, endPoint, null, 0.0f, false);
        }

        /// <summary>
        /// 设置目标点
        /// </summary>
        /// <param name="plyaer"></param>
        /// <param name="endPoint"></param>
        /// <param name="completeDistance">剩余多少距离完成移动</param>
        /// <returns></returns>
        public GameObject SetTargetPoint(GameObject plyaer, Vector3 endPoint, float completeDistance, bool isStop = true)
        {
            return SetTargetPoint(plyaer, endPoint, null, completeDistance, isStop);
        }

        /// <summary>
        /// 设置目标点
        /// </summary>
        /// <param name="plyaer"></param>
        /// <param name="endPoint"></param>
        /// <param name="startMoveCallback"></param>
        /// <param name="endMoveCallback"></param>
        /// <returns></returns>
        public GameObject SetTargetPoint(GameObject plyaer, Vector3 endPoint, UnityAction<GameObject> endMoveCallback)
        {
            return SetTargetPoint(plyaer, endPoint, endMoveCallback, 0.0f, false);
        }

        /// <summary>
        /// 设置目标点
        /// </summary>
        /// <param name="player"></param>
        /// <param name="endPoint"></param>
        /// <param name="startMoveCallback"></param>
        /// <param name="endMoveCallback"></param>
        /// <param name="completeDistance">剩余多少距离完成移动</param>
        /// <returns>id</returns>
        public GameObject SetTargetPoint(GameObject player, Vector3 endPoint, UnityAction<GameObject> endMoveCallback, float completeDistance = 0.0f, bool isStop = false)
        {
            //遍历一下导航列表看看对象是否重复，如果重复证明该对象正在移动中，则切换目标点
            NavigationTaskClass findNtc = ntcList.Find((x) => player.Equals(x.Player));
            if (findNtc.IsNotNull())
            {
                NavMeshAgent findNma = findNtc.Player.GetComponent<NavMeshAgent>();
                findNma.SetDestination(endPoint);
                return findNtc.Player;
            }
            NavMeshAgent nma = player.GetComponent<NavMeshAgent>();
            if (nma.IsNotNull())
            {
                nma.SetDestination(endPoint);
                NavigationTaskClass ntc = new NavigationTaskClass();
                ntc.Player = player;
                ntc.EndMoveCallback = endMoveCallback;
                ntc.CompleteDistance = completeDistance;
                ntc.IsStop = isStop;
                ntcList.Add(ntc);
                return player;
            }
            else
            {
                throw new MissingComponentException("需要移动的对象身上没有挂载NavMeshAgent组件");
            }
        }

        /// <summary>
        /// 查找一个导航
        /// </summary>
        /// <param name="player"></param>
        /// <returns></returns>
        public NavMeshAgent FindNavMeshAgent(GameObject player)
        {
            NavigationTaskClass ntc = ntcList.Find((nma) => player.Equals(nma.Player));
            if (ntc.IsNotNull())
            {
                return ntc.Player.GetComponent<NavMeshAgent>();
            }
            return null;
        }

        /// <summary>
        /// 下一个点
        /// </summary>
        /// <param name="player"></param>
        /// <returns></returns>
        public Vector3 NextPoint(GameObject player)
        {
            NavigationTaskClass ntc = ntcList.Find((nma) => player.Equals(nma.Player));
            if (ntc.IsNotNull())
            {
                return ntc.Player.GetComponent<NavMeshAgent>().nextPosition;
            }
            return Vector3.zero;
        }

        /// <summary>
        /// 距离目的地剩下的距离
        /// </summary>
        /// <param name="player"></param>
        /// <returns></returns>
        public float RemainDistance(GameObject player)
        {
            NavigationTaskClass ntc = ntcList.Find((nma) => player.Equals(nma.Player));
            if (ntc.IsNotNull())
            {
                return ntc.Player.GetComponent<NavMeshAgent>().remainingDistance;
            }
            return 0;
        }

        /// <summary>
        /// 终点
        /// </summary>
        /// <param name="player"></param>
        /// <returns></returns>
        public Vector3 EndPoint(GameObject player)
        {
            NavigationTaskClass ntc = ntcList.Find((nma) => player.Equals(nma.Player));
            if (ntc.IsNotNull())
            {
                return ntc.Player.GetComponent<NavMeshAgent>().destination;
            }
            return Vector3.zero;
        }

        /// <summary>
        /// 延时用的
        /// </summary>
        private void Update()
        {
            for (int i = 0; i < ntcList.Count; i++)
            {
                NavigationTaskClass ntc = ntcList[i];
                NavMeshAgent nma = ntc.Player.GetComponent<NavMeshAgent>();
                if (nma.remainingDistance <= ntc.CompleteDistance)
                {
                    //是否立刻停止移动
                    if (ntc.IsStop)
                    {
                        nma.isStopped = true;
                    }
                    //移动完成回调
                    if (ntc.EndMoveCallback.IsNotNull())
                    {
                        ntc.EndMoveCallback(ntc.Player);
                    }
                    ntcList.RemoveAt(i);
                    i--;
                }
            }
        }

        /// <summary>
        /// 停止移动
        /// </summary>
        /// <param name="player"></param>
        public void Stop(GameObject player)
        {
            NavigationTaskClass ntc = ntcList.Find((nma) => player.Equals(nma.Player));
            if (ntc.IsNotNull())
            {
                NavMeshAgent nma = ntc.Player.GetComponent<NavMeshAgent>();
                if (!nma.isStopped)
                {
                    nma.isStopped = true;
                }
            }
        }

    }

}

